package com.exception;

import com.common.ResultBean;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;

/**
 * 全局异常拦截
 */
@Aspect
@Component
@Slf4j
@Order(-99)
public class ExceptionAOP {

    @Pointcut("execution(public com.common.ResultBean *(..))")
    public void controllerMethod() {

    }

    @Around("controllerMethod()")
    public Object handleLog(ProceedingJoinPoint pjp) {
        long startTime = System.currentTimeMillis();

        ResultBean<?> resultBean;
        try {
            resultBean = (ResultBean<?>) pjp.proceed();
        } catch (Throwable throwable) {
            log.error(throwable.getMessage());
            resultBean = handleException(throwable);
        }
        long elapsedTime = System.currentTimeMillis() - startTime;

        log.info("[{}]use time: {}", pjp.getSignature(), elapsedTime);
        return resultBean;
    }

    /**
     * 异常信息处理
     *
     * @param throwable 捕获异常
     * @return 异常处理结果
     */
    private ResultBean<String> handleException(Throwable throwable) {
        if (throwable instanceof CheckException) {
            return ResultBean.error(throwable.getMessage());
        } else if (throwable instanceof AccessDeniedException) {
            return ResultBean.error("用户无访问权限");
        } else if (throwable instanceof AuthenticationException) {
            // 处理login接口登陆异常
            return ResultBean.error("用户身份信息认证失败");
        } else if (throwable instanceof BindException) {
            return ResultBean.error("参数有误");
        } else {
            return ResultBean.error("服务器异常");
        }
    }
}
